package com.ruoyi.business.service.asyncservice;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.bizsys.domain.*;
import com.ruoyi.bizsys.mapper.*;
import com.ruoyi.bizsys.service.ICustomerInfoService;
import com.ruoyi.bizsys.service.ILoanDeferredOrderService;
import com.ruoyi.bizsys.utils.BizConstants;
import com.ruoyi.bizsys.vo.MonnifyReservedAccount;
import com.ruoyi.business.common.AsyncService;
import com.ruoyi.business.component.RepaymentMqSendService;
import com.ruoyi.business.processIou.service.ProcessForIouDefferredService;
import com.ruoyi.business.service.IBLoanInfoService;
import com.ruoyi.business.service.ICustVaService;
import com.ruoyi.business.service.IDoRepaymentLastService;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.client.producer.SendStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;

/**
 * @author wqg
 * @description 还款相关的异步执行写在这里。其他需要沟通后写入
 * @date 2022/6/6
 */
@Slf4j
@Service
public class AsyncRepaymentService {
    @Autowired
    AccountFlowMapper accountFlowMapper;
    @Autowired
    RepaymentMqSendService repaymentMqService;
    @Resource
    LoanIouMapper loanIouMapper;
    @Autowired
    ProductDeferredInfoMapper productDeferredInfoMapper;

    @Autowired
    ProductInfoMapper productInfoMapper;

    @Autowired
    LoanDeferredOrderMapper loanDeferredOrderMapper;

    @Autowired
    ILoanDeferredOrderService loanDeferredOrderService;
    @Autowired
    @Lazy
    IBLoanInfoService bLoanInfoService;
    @Autowired
    ProcessForIouDefferredService processForIouDefferredService;

    @Autowired
    IDoRepaymentLastService doRepaymentLastService;

    @Autowired
    ICustomerInfoService customerInfoService;
    @Autowired
    AsyncService asyncService;

    @Autowired
    ICustVaService custVaService;

    /**
     * 异步更新账目流水，
     */
    @Async("threadPoolTaskExecutor")
    public void asyncInsertAccountFlow(AccountFlow accountFlow) {
        accountFlowMapper.insertByIndex(accountFlow);
    }

    /**
     * 异步钱包购买延期
     *
     * @param loanDeferredOrder
     */
    @Async("threadPoolTaskExecutor")
    public void asyncWalletBuyDefer(LoanDeferredOrder loanDeferredOrder, boolean isColletion) {
        log.info("处理催钱包购买延期:{}", loanDeferredOrder.toString());
        LoanIou loanIou = loanIouMapper.getLoanIouByLoanSerialNo(loanDeferredOrder.getLoanSerialNo());
        ProductDeferredInfo productDeferredInfo = productDeferredInfoMapper.selectById(loanDeferredOrder.getProductDeferredId());
        BigDecimal minPay = processForIouDefferredService.getMinPay(loanIou, productDeferredInfo);
        BigDecimal leftWalletAmt = doRepaymentLastService.getWalletAmount(loanIou.getCustNo());
        if (leftWalletAmt.compareTo(BigDecimal.ZERO) <= 0) {
            log.info("处理催钱包购买延期:minPay:{},leftWalletAmt:{},不够，则触发短信提醒用户使用VA还延期费用，{}", minPay, leftWalletAmt, loanDeferredOrder.getLoanSerialNo());
            // 则触发短信提醒用户使用VA还延期费用
            if (isColletion) {
                sendSmsForVa(loanIou, minPay);
            }
            return;
        }
        log.info("处理催钱包购买延期:minPay:{},leftWalletAmt:{},可以还款，钱包冻结等,{}", minPay, leftWalletAmt, loanDeferredOrder.getLoanSerialNo());
        // 得到选择的延期产品需要支付的金额，远程获取钱包，钱包不够，就返回钱包最小的金额
        // 进行冻结，冻结可能金额会变化
        JSONObject amtWalletObj = doRepaymentLastService.getAmtWallet(minPay, loanIou.getCustNo(), loanIou.getLoanSerialNo(), true);
        BigDecimal amtWallet = amtWalletObj.getBigDecimal("amtWallet");
        String walletNo = amtWalletObj.getString("walletOrderNo");
        if (amtWallet.compareTo(minPay) < 0) {
            log.info("处理催钱包购买延期:minPay:{},leftWalletAmt:{},解冻钱包,不够，则触发短信提醒用户使用VA还延期费用,{}", minPay, leftWalletAmt, loanDeferredOrder.getLoanSerialNo());
            // 解冻钱包
            doRepaymentLastService.updateWalletOrderToFailed(walletNo, true);
            if (isColletion) {
                sendSmsForVa(loanIou, minPay);
            }
            return;
        }
        log.info("处理催钱包购买延期:minPay:{},leftWalletAmt:{},足够{}", minPay, leftWalletAmt, loanDeferredOrder.getLoanSerialNo());
        RepaymentOrder repaymentOrder = bLoanInfoService.createRepaymentOrderForDeferWalletSuccess(
                loanIou,
                BizConstants.LOAN_REPAYMENT_ORDER_TYPE_COLLECTION_WALLET_BUY_DEFER,
                "Active",
                loanDeferredOrder, amtWallet, walletNo);
        if (null != repaymentOrder) {
            try {
                SendResult sendResult = repaymentMqService.selfdeferWalletForAllPayRepaymentMq(loanIou, productDeferredInfo, repaymentOrder, amtWallet, walletNo);
                if (!SendStatus.SEND_OK.equals(sendResult.getSendStatus())) {
                    log.info("处理催钱包购买延期:钱包全额支付延期还款.mq发送失败,{}", loanDeferredOrder.getLoanSerialNo());
                    doRepaymentLastService.updateWalletOrderToFailed(walletNo, true);
                    return;
                }
            } catch (Exception e) {
                log.error("处理催钱包购买延期:钱包全额支付延期还款.mq发送失败,{}", loanDeferredOrder.getLoanSerialNo(), e);
                doRepaymentLastService.updateWalletOrderToFailed(walletNo, true);
                throw new RuntimeException(e);
            }
        } else {
            log.info("处理催钱包购买延期:钱包全额支付延期还款，创建订单失败,{}", loanDeferredOrder.getLoanSerialNo());
            doRepaymentLastService.updateWalletOrderToFailed(walletNo, true);
        }

    }

    private void sendSmsForVa(LoanIou loanIou, BigDecimal minPay) {
        log.info("处理催钱包购买延期,不够，则触发短信提醒用户使用VA还延期费用,{},{}", loanIou.getCustNo(), minPay);
        String userId = customerInfoService.getUserIdByCustNo(loanIou.getCustNo());
        MonnifyReservedAccount monnifyReservedAccount = custVaService.getVaReservedAccount(loanIou.getCustNo());
        asyncService.sendVaSms(userId, monnifyReservedAccount, minPay);
    }
}
